#pragma once

#include "argument.h"
#include "map.h"

#define common_define_enum(T, ...) \
enum T  \
{ \
  __VA_ARGS__, \
  T##_end, \
  T##_begin = common_args_get_first (__VA_ARGS__), \
  T##_last = common_args_get_last (__VA_ARGS__) \
}; \
\
__define_enum_to_string (T, __VA_ARGS__)

#define common_for_each_enum(variable_name, T) \
  for (enum T variable_name = T##_begin; \
    variable_name < T##_end; ++variable_name)

#define __enum_case(x) \
  case x: \
    return #x; \
    break;

#define __define_enum_to_string(T, ...) \
inline const char * \
T##_to_string (enum T t) \
{ \
  switch (t) \
  { \
    common_map (__enum_case, __VA_ARGS__) \
    default: \
    return "undefined"; \
    break; \
  } \
}

#ifdef common_namespace

#define define_enum(...) common_define_enum (__VA_ARGS__)

#define for_each_enum(...) common_for_each_enum (__VA_ARGS__)

#endif
